﻿using LxBasic;
using LxLESS;
using System;

namespace LxCore
{
    public class EquationConnectBase : JointHead, IJointIteration
    {
        //local
        protected double[] A14;
        protected double[] A41;
        //share
        protected EquationWithTransTerm O_Matrix;
        protected EquationWithTransTerm N_Matrix;
        protected double[] O_XInn;
        protected double[] N_XInn;
        protected double[] O_XBou;
        protected double[] N_XBou;
        public override void CheckCreate(FvJoint joint)
        {
            base.CheckCreate(joint);
            CheckCreator.ArrayStrict(ref A14, ConFaces.Length);
            CheckCreator.ArrayStrict(ref A41, ConFaces.Length);
        }
        protected void setMatrix(EquationWithTransTerm OMatrix, EquationWithTransTerm NMatrix)
        {
            this.O_Matrix = OMatrix;
            this.O_XInn = O_Matrix.InnX;
            this.O_XBou = O_Matrix.BouX;
            this.N_Matrix = NMatrix;
            this.N_XInn = N_Matrix.InnX;
            this.N_XBou = N_Matrix.BouX;
        }

        public void Iterate_Copy_xCommonArray(ThreadInfo threadInfo)
        {
            CopyBound(O_Matrix.InnFaceShare, N_Matrix.InnFaceShare, threadInfo);
        }
        public void Iterate_Copy_xArray(ThreadInfo threadInfo)
        {
            CopyBound(O_Matrix.InnX, N_Matrix.InnX, threadInfo);
        }
        protected void CopyBound(double[] OArray, double[] NArray, ThreadInfo threadInfo)
        {
            double[] O_ABou = O_Matrix.ABouH;
            double[] N_ABou = N_Matrix.ABouH;
            int oStart = OBound.FaceIdx.Start;
            int nStart = NBound.FaceIdx.Start;
            {
                (int i1, int endp1) = Joint.FaceIdx.Split(threadInfo);
                for (; i1 < endp1; i1++)
                {
                    ref var j = ref ConFaces[i1];
                    O_ABou[i1 + oStart] = A14[i1] * NArray[j.N_InnCell];
                    N_ABou[i1 + nStart] = A41[i1] * OArray[j.O_InnCell];
                }
            }
        }

        public void BiCGStabIte_Copy_yArray(ThreadInfo threadInfo)
        {
            CopyBound(Joint.LESSJoint.O_BiCGZone.y, Joint.LESSJoint.N_BiCGZone.y, threadInfo);
        }
        public void BiCGStabIte_Copy_zArray(ThreadInfo threadInfo)
        {
            CopyBound(Joint.LESSJoint.O_BiCGZone.z, Joint.LESSJoint.O_BiCGZone.z, threadInfo);
        }
        public virtual void FormAbOnFaces(ThreadInfo threadInfo)
        {
            throw new NotImplementedException();
        }

        public virtual void UpdateJointValue(ThreadInfo threadInfo)
        {
            throw new NotImplementedException();
        }

        public void AMGIte_Restrict_A(ThreadInfo threadInfo)
        {
            var coarse = Joint.LESSJoint.MGJoints[0];
            coarse.HelpRestrict_ALU(A14, A41, threadInfo);
        }

        public LESSJoint GetLessJoint()
        {
            return Joint.LESSJoint;
        }
    }
}

//double[] O_ABou = O_Matrix.BouAH;
//double[] N_ABou = N_Matrix.BouAH;
//{
//    (int i1, int endp1) = OBound.CellIdx.Split(threadInfo);
//    for (; i1 < endp1; i1++)
//    {
//        double aluproduct = 0;
//        foreach (var jid in O_Side[i1].Joints)
//        {
//            aluproduct += A14[jid] * NArray[Joints[jid].N_InnCell];
//        }
//        O_ABou[i1] = aluproduct;
//    }
//}
//{
//    (int i1, int endp1) = NBound.CellIdx.Split(threadInfo);
//    for (; i1 < endp1; i1++)
//    {
//        double aluproduct = 0;
//        foreach (var jid in N_Side[i1].Joints)
//        {
//            aluproduct += A41[jid] * OArray[Joints[jid].O_InnCell];
//        }
//        N_ABou[i1] = aluproduct;
//    }
//}

//double[] O_ALUO = O_Matrix.ALUO;
//double[] N_ALUO = N_Matrix.ALUO;
//{
//    (int i1, int endp1) = OBound.CellIdx.Split(threadInfo);
//    for (; i1 < endp1; i1++)
//    {
//        double aluproduct = 0;
//        ref FvCell ocell = ref O_Cells[i1];
//        foreach (var jid in ocell.OFaces)
//        {
//            aluproduct += A14[jid] * NArray[Pairs[jid].N_InnCell];
//        }
//        O_ALUO[ocell.NFaces[0]] = aluproduct;
//    }
//}
//{
//    (int i1, int endp1) = NBound.CellIdx.Split(threadInfo);
//    for (; i1 < endp1; i1++)
//    {
//        double aluproduct = 0;
//        ref FvCell ncell = ref N_Cells[i1];
//        foreach (var pid in N_Cells[i1].OFaces)
//        {
//            aluproduct += A41[pid] * OArray[Pairs[pid].O_InnCell];
//        }
//        N_ALUO[ncell.NFaces[0]] = aluproduct;
//    }
//}